﻿using Microsoft.AspNetCore.Http;
using System.Diagnostics;
using System.Net.Http;
using System.Net;
using WLYT.Application.Interfaces;
using WLYT.Domain.Entries;
using Microsoft.IdentityModel.Tokens;

namespace WLYT.WMS.Component
{
    public class MessageInterceptorMiddleware(RequestDelegate next, IBaseService<LogRecord> logService, ILogger<MessageInterceptorMiddleware> logger)
    {
        public async Task Invoke(HttpContext context)
        {
            LogRecord log = new LogRecord
            {
                Method = context.Request.Method,
                RequestUri = context.Request.Path,
                IP = context.Connection.RemoteIpAddress?.ToString() ?? "",
                CreateTime = DateTime.Now
            };
            if (context.Request.Method == "GET")
            {
                log.RequestContent = context.Request.QueryString.Value ?? "";
            }
            else
            {
                context.Request.EnableBuffering();
                using (MemoryStream memoryStream = new())
                {
                    await context.Request.Body.CopyToAsync(memoryStream);
                    context.Request.Body.Position = 0;
                    memoryStream.Position = 0;
                    using (StreamReader streamReader = new(memoryStream))
                    {
                        log.RequestContent = await streamReader.ReadToEndAsync();
                    }
                }
            }

            Stream originalBody = context.Response.Body;
            try
            {
                using (MemoryStream memoryStream = new())
                {
                    context.Response.Body = memoryStream;
                    Stopwatch watch = new();
                    watch.Start();
                    try
                    {
                        await next.Invoke(context);
                    }
                    catch (Exception ex)
                    {
                        logger.LogError(ex.ToString());
                    }
                    watch.Stop();
                    log.Timer = (int)watch.ElapsedMilliseconds;
                    memoryStream.Position = 0;
                    await memoryStream.CopyToAsync(originalBody);
                    using (StreamReader streamReader = new(memoryStream))
                    {
                        memoryStream.Position = 0;
                        log.ResponseContent = await streamReader.ReadToEndAsync();
                        log.IsSuccess = log.ResponseContent.Contains("\"Code\":0")
                            || log.ResponseContent.Contains("\"success\":true")
                            || log.ResponseContent.Contains("\"state\":1")
                            || log.ResponseContent.Contains("\"respCode\":1000");
                    }
                }
            }
            finally
            {
                context.Response.Body = originalBody;
            }
            try
            {
                await logService.SplitTableInsertAsync(log);
            }
            catch (Exception)
            {
            }
        }
    }
}
